package com.cat.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import javax.annotation.Resource;

import org.dom4j.DocumentException;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.RepositoryService;

import com.abigdreamer.arkflow.WorkflowNode;
import com.cat.business.BizWorkFlowBusinessService;
import com.cat.entity.BizWorkflow;
import com.cat.entity.TbRole;
import com.cat.service.common.BizWorkFlowService;
import com.cat.service.common.RoleService;
import com.cat.util.TwoTuple;

public class WorkflowAction extends BaseAction {

	private static final long serialVersionUID = -2409066480042411609L;

	private ProcessEngine processEngine;
	@Resource
	private BizWorkFlowBusinessService workflowBusinessService;
	@Resource
	private RoleService roleservice;
	@Resource
	private BizWorkFlowService bizFlowService;
	
	private List<WorkflowNode> flowList = new ArrayList<WorkflowNode>();
	private List<TbRole> roleList;
	private String assignee;
	private String form;
	private WorkflowNode wfp;
	private boolean success;
	private BizWorkflow bizFlow;
	private String deploymentDbid;

	public String initAddWorkFlowPage() {
		if (deploymentDbid != null && !deploymentDbid.equals("")) {
			bizFlow = bizFlowService.getByDeploymentId(Integer.valueOf(deploymentDbid));
			return "updateWorkflow";
		} else {
			bizFlow = new BizWorkflow();
			bizFlow.setWorkflowDescribe("");
			return "addWorkflow";
		}
	}

	private String isEdit;
	private String workflowData;
	
	public String editWorkflow() throws UnsupportedEncodingException {

		System.out.println(workflowData);
		
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			TwoTuple<List<WorkflowNode>, WorkflowNode> info = workflowBusinessService.getJson(workflowData);
			List<WorkflowNode> states = info.first;
			WorkflowNode workflow = info.second;
			
			map.put("stateList", states);
			map.put("workflow", workflow);
			
			if (isEdit.equals("0")) {
				// 新增
				List<BizWorkflow> workflowList = workflowBusinessService.getByWorkflowName(workflow.getName());
				if (workflowList != null && workflowList.size() > 0) {
					map.put("f", "f");
					map.put("m", "流程名称：" + workflow.getName() + "已存在，不可重复添加！");
					return mapAjaxJson(map);
				}
			}
			for (WorkflowNode state : states) {
				// 建立审批节点的TABLE
				if (!state.getType().equals("start") && !state.getType().equals("end")) {
					flowList.add(state);
				}
			}

			roleList = roleservice.getAll();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		map.put("f", "s");
		map.put("flowList", flowList);
		map.put("workflowData", workflowData);
		map.put("roleList", roleList);
		return mapAjaxJson(map);
	}

	public String initFlow() {
		return "flow";
	}

	public String saveFlow() {
		
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			TwoTuple<List<WorkflowNode>, WorkflowNode> info = workflowBusinessService.getJson(workflowData);
			
			List<WorkflowNode> states = info.first;
			WorkflowNode workflow = info.second;
			
			map.put("stateList", states);
			map.put("workflow", workflow);
			
			HashMap<String, String> idNameMap = new HashMap<String, String>();
			for (WorkflowNode state : states) {
				idNameMap.put(state.getProcessName(), state.getName());
				for (WorkflowNode flow : flowList) {
					if (state.getName().equals(flow.getName())) {
						if (state.getType().equals("decision")) {
							state.setExpr(flow.getExpr());
						} else {
							state.setAssignType(flow.getAssignType());
							state.setAssignee(flow.getAssignee());
							state.setAssignValue(flow.getAssignValue());
							state.setForm(flow.getForm());
						}
					}
				}
			}
			String zipPath = workflowBusinessService.addWorkflow(states, idNameMap, workflow);
			if (!zipPath.equals("")) {
				// 5.发布
				RepositoryService repositoryService = processEngine.getRepositoryService();
				File flowFile = new File(zipPath);
				InputStream is = new FileInputStream(flowFile);
				ZipInputStream zis = new ZipInputStream(is);
				// 发起流程，仅仅就是预定义任务，即在系统中创建一个流程，这是全局的，与具体的登陆
				// 用户无关。然后，在启动流程时，才与登陆用户关联起来
				String did = repositoryService.createDeployment().addResourcesFromZipInputStream(zis).deploy();

				zis.close();
				is.close();
				System.out.println("did: " + did);
				System.out.println("发布流程成功<br />");
				BizWorkflow flow = new BizWorkflow();
				flow.setWorkflowName(workflow.getName());
				flow.setDeploymentId(Integer.valueOf(did));
				flow.setWorkflowDescribe(workflowData);
				workflowBusinessService.saveWork(flow);
			}
			map.put("f", "s");
		} catch (Exception e) {
			e.printStackTrace();
			map.put("f", "f");
			map.put("m", e.toString());
		}
		return mapAjaxJson(map);
	}

	public String getWorkflowData() {
		return workflowData;
	}

	public void setWorkflowData(String workflowData) {
		this.workflowData = workflowData;
	}

	public List<WorkflowNode> getFlowList() {
		return flowList;
	}

	public void setFlowList(List<WorkflowNode> flowList) {
		this.flowList = flowList;
	}

	public String getAssignee() {
		return assignee;
	}

	public void setAssignee(String assignee) {
		this.assignee = assignee;
	}

	public String getForm() {
		return form;
	}

	public void setForm(String form) {
		this.form = form;
	}

	public WorkflowNode getWfp() {
		return wfp;
	}

	public void setWfp(WorkflowNode wfp) {
		this.wfp = wfp;
	}

	public boolean isSuccess() {
		return success;
	}

	public void setSuccess(boolean success) {
		this.success = success;
	}

	public void setProcessEngine(ProcessEngine processEngine) {
		this.processEngine = processEngine;
	}

	public ProcessEngine getProcessEngine() {
		return processEngine;
	}

	public List<TbRole> getRoleList() {
		return roleList;
	}

	public void setRoleList(List<TbRole> roleList) {
		this.roleList = roleList;
	}

	public BizWorkflow getBizFlow() {
		return bizFlow;
	}

	public void setBizFlow(BizWorkflow bizFlow) {
		this.bizFlow = bizFlow;
	}

	public String getDeploymentDbid() {
		return deploymentDbid;
	}

	public void setDeploymentDbid(String deploymentDbid) {
		this.deploymentDbid = deploymentDbid;
	}

	public String getIsEdit() {
		return isEdit;
	}

	public void setIsEdit(String isEdit) {
		this.isEdit = isEdit;
	}

}
